using System.Linq;
using Magiq.Support;
using Magiq.Tests.Support;
using Magiq.Tests.TestModel;
using NUnit.Framework;

namespace Magiq.Tests.MagiqToObjects {
    [TestFixture]
    public class EnumerableSourceFinderTests {
        private readonly TestDomain<TestClass> domain = new TestDomain<TestClass>();

        [Test]
        public void ShouldProvideFromQueryable() {
            var items = domain.TestClassInstances.AsQueryable();
            var source = new EnumerableSource(items);
            source.List.Should(Be.EqualTo(domain.TestClassInstances));
            source.IsQuery.Should(Be.False);
        }

        [Test]
        public void ShouldProvideFromSingleList() {
            var items = domain.TestClassInstances;
            var source = new EnumerableSource(items);
            source.List.Should(Be.EqualTo(domain.TestClassInstances));
            source.IsQuery.Should(Be.False);
        }

        [Test]
        public void ShouldProvideFromWhere() {
            var items = domain.TestClassInstances.Where(x => x.StringProperty == "sarasa");
            var source = new EnumerableSource(items);
            source.List.Should(Be.EqualTo(domain.TestClassInstances));
            source.IsQuery.Should(Be.True);
        }

        [Test]
        public void ShouldProvideFromWhereQueryable() {
            var items = domain.TestClassInstances.AsQueryable().Where(x => x.StringProperty == "sarasa");
            var source = new EnumerableSource(items);
            source.List.Should(Be.EqualTo(domain.TestClassInstances));
            source.IsQuery.Should(Be.True);
        }

        [Test]
        public void ShouldProvideFromWhereWithFilterChain() {
            var items = domain.TestClassInstances.Where(x => x.StringProperty == "sarasa").Where(x => x.IntProperty == 4);
            var source = new EnumerableSource(items);
            source.List.Should(Be.EqualTo(domain.TestClassInstances));
            source.IsQuery.Should(Be.True);
        }

        [Test]
        public void ShouldProvideFromWhereWithFilterChainQueryable() {
            var items =
                domain.TestClassInstances.AsQueryable().Where(x => x.StringProperty == "sarasa").Where(x => x.IntProperty == 4);
            var source = new EnumerableSource(items);
            source.List.Should(Be.EqualTo(domain.TestClassInstances));
            source.IsQuery.Should(Be.True);
        }

        [Test]
        [ExpectedException(typeof (SourceIsFixedSizeException))]
        public void ShouldThrowSourceIsFixedSizeExceptionIfSourceIsAnArray() {
            var items = domain.TestClassInstances.ToArray();
            new EnumerableSource(items);
        }

        [Test]
        [ExpectedException(typeof (SourceIsFixedSizeException))]
        public void ShouldThrowSourceIsFixedSizeExceptionIfSourceIsAReadOnlyList() {
            var items = domain.TestClassInstances.AsReadOnly();
            new EnumerableSource(items);
        }
    }
}